﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections.ObjectModel;
using PromoServer.Library.Entities;

namespace PromoServer.Library.Data
{
    public class PSData
    {
        public PSData() { }

        public int DeviceCount()
        {
            try
            {
                // Count registered devices
                int deviceCount = 0;
                
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                DataTable dtDevices = taDevices.GetData();

                foreach (DataRow dr in dtDevices.Rows)
                {
                    deviceCount += 1;
                }

                return deviceCount;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.DeviceCount", ex.Message, true);
                return -1;
            }
        }

        public List<Device> GetDevices()
        {
            try
            {
                // Load registered devices from db
                List<Device> registeredDevices = new List<Device>();

                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                DataTable dtDevices = taDevices.GetData();

                int deviceID = 0, displayWidth = 0, displayHeight = 0;
                string hostName = null, displayName = null, displayLayout = null;

                Device device;
                foreach (DataRow dr in dtDevices.Rows)
                {
                    deviceID = Convert.ToInt32(dr["DeviceID"].ToString());
                    hostName = dr["HostName"].ToString();
                    displayName = dr["DisplayName"].ToString();
                    displayLayout = dr["DisplayLayout"].ToString();
                    displayWidth = Convert.ToInt32(dr["DisplayWidth"].ToString());
                    displayHeight = Convert.ToInt32(dr["DisplayHeight"].ToString());

                    device = new Device(deviceID, hostName, displayName, displayLayout, displayWidth, displayHeight);

                    registeredDevices.Add(device);
                }              

                return registeredDevices;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetDevices", ex.Message, true);
                return null;
            }
        }

        public ObservableCollection<Device> GetDeviceCollection()
        {
            try
            {
                // Load registered devices from db
                ObservableCollection<Device> registeredDevices = new ObservableCollection<Device>();

                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                DataTable dtDevices = taDevices.GetData();

                int deviceID = 0, displayWidth = 0, displayHeight = 0;
                string hostName = null, displayName = null, displayLayout = null;

                Device device;
                foreach (DataRow dr in dtDevices.Rows)
                {
                    deviceID = Convert.ToInt32(dr["DeviceID"].ToString());
                    hostName = dr["HostName"].ToString();
                    displayName = dr["DisplayName"].ToString();
                    displayLayout = dr["DisplayLayout"].ToString();
                    displayWidth = Convert.ToInt32(dr["DisplayWidth"].ToString());
                    displayHeight = Convert.ToInt32(dr["DisplayHeight"].ToString());

                    device = new Device(deviceID, hostName, displayName, displayLayout, displayWidth, displayHeight);

                    registeredDevices.Add(device);
                }  

                return registeredDevices;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetDeviceCollection", ex.Message, true);
                return null;
            }
        }

        public Device GetDevice(int DeviceID)
        {
            try
            {
                // Load registered device from db
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                DataTable dtDevices = taDevices.GetDataByDeviceID(DeviceID);

                int deviceID = 0, displayWidth = 0, displayHeight = 0;
                string hostName = null, displayName = null, displayLayout = null;

                foreach (DataRow dr in dtDevices.Rows)
                {
                    deviceID = Convert.ToInt32(dr["DeviceID"].ToString());
                    hostName = dr["HostName"].ToString();
                    displayName = dr["DisplayName"].ToString();
                    displayLayout = dr["DisplayLayout"].ToString();
                    displayWidth = Convert.ToInt32(dr["DisplayWidth"].ToString());
                    displayHeight = Convert.ToInt32(dr["DisplayHeight"].ToString());
                }

                Device device = new Device(deviceID, hostName, displayName, displayLayout, displayWidth, displayHeight);

                return device;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetDevice", ex.Message, true);
                return null;
            }
        }

        public Device GetNewestDevice()
        {
            try
            {
                // Load registered device from db
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                DataTable dtDevices = taDevices.GetDataByNewestDevice();

                int deviceID = 0, displayWidth = 0, displayHeight = 0;
                string hostName = null, displayName = null, displayLayout = null;

                foreach (DataRow dr in dtDevices.Rows)
                {
                    deviceID = Convert.ToInt32(dr["DeviceID"].ToString());
                    hostName = dr["HostName"].ToString();
                    displayName = dr["DisplayName"].ToString();
                    displayLayout = dr["DisplayLayout"].ToString();
                    displayWidth = Convert.ToInt32(dr["DisplayWidth"].ToString());
                    displayHeight = Convert.ToInt32(dr["DisplayHeight"].ToString());
                }

                Device device = new Device(deviceID, hostName, displayName, displayLayout, displayWidth, displayHeight);

                return device;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetNewestDevice", ex.Message, true);
                return null;
            }
        }

        public int GetDeviceIDByHostName(string hostName)
        {
            try
            {
                // Get device id
                int deviceID;
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                deviceID = (int)taDevices.GetDeviceIDByHostName(hostName);
                return deviceID;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetDeviceIDByHostName", ex.Message, true);
                return -1;
            }
        }

        public string GetDisplayNameByHostName(string hostName)
        {
            try
            {
                // Get device id
                string displayName = string.Empty;
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                displayName = (string)taDevices.GetDisplayNameByHostName(hostName);
                return displayName;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetDeviceIDByHostName", ex.Message, true);
                return string.Empty;
            }
        }

        public bool AddDevice(string hostName, string displayName, string displayLayout, int displayWidth, int displayHeight)
        {
            try
            {
                // Add new device to db
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                taDevices.InsertDevice(hostName, displayName, displayLayout, displayWidth, displayHeight);
                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.AddDevice", ex.Message, true);
                return false;
            }
        }

        public bool DeleteDevice(Device device)
        {
            try
            {
                // Delete device
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                taDevices.DeleteDevice(device.DeviceID);

                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.DeleteDevice", ex.Message, true);
                return false;
            }
        }

        public bool UpdateDisplayName(int deviceID, string displayName)
        {
            try
            {
                // Add new device to db
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                taDevices.UpdateDisplayName(displayName, deviceID);
                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.UpdateDisplayName", ex.Message, true);
                return false;
            }
        }

        public void UpdateDisplayName(Device device)
        {
            try
            {
                // Add new device to db
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                taDevices.UpdateDisplayName(device.DisplayName, device.DeviceID);
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.UpdateDisplayName", ex.Message, true);
            }
        }

        public bool UpdateDeviceResolution(Device device)
        {
            try
            {
                // Add new device to db
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                taDevices.UpdateResolution(device.DisplayWidth, device.DisplayHeight, device.DeviceID);
                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.UpdateDeviceResolution", ex.Message, true);
                return false;
            }
        }

        public bool UpdateDeviceResolution(int deviceID, int displayWidth, int displayHeight)
        {
            try
            {
                // Add new device to db
                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                taDevices.UpdateResolution(displayWidth, displayHeight, deviceID);
                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.UpdateDeviceResolution", ex.Message, true);
                return false;
            }
        }

        public int GetDeviceWidth(int deviceID)
        {
            try
            {
                // Get device display width from db
                int displayWidth;

                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                displayWidth = (int)taDevices.GetDisplayWidth(deviceID);

                return displayWidth;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetDeviceWidth", ex.Message, true);
                return -1;
            }
        }

        public int GetDeviceHeight(int deviceID)
        {
            try
            {
                // Get device display width from db
                int displayHeight;

                PSDataSetTableAdapters.DevicesTableAdapter taDevices = new PSDataSetTableAdapters.DevicesTableAdapter();
                displayHeight = (int)taDevices.GetDisplayHeight(deviceID);

                return displayHeight;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetDeviceHeight", ex.Message, true);
                return -1;
            }
        }

        public List<Layout> GetLayouts()
        {
            try
            {
                List<Layout> layouts = new List<Layout>();

                PSDataSetTableAdapters.LayoutHeaderTableAdapter taHeader = new PSDataSetTableAdapters.LayoutHeaderTableAdapter();
                PSDataSetTableAdapters.LayoutDetailTableAdapter taDetail = new PSDataSetTableAdapters.LayoutDetailTableAdapter();

                // Load layout header records
                DataTable dtLayoutHeader = taHeader.GetData();

                // Get details/content for each layout and add to master layout list
                Layout tempLayout;
                foreach (DataRow dr in dtLayoutHeader.Rows)
                {
                    tempLayout = new Layout(Convert.ToInt32(dr["LayoutID"].ToString()), dr["Name"].ToString(), Convert.ToInt32(dr["ScheduleID"].ToString()));
                    tempLayout.Content = new ObservableCollection<LayoutContent>(GetLayoutDetail(tempLayout.LayoutID));
                    layouts.Add(tempLayout);
                }

                // Return list of all layouts
                return layouts;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetLayouts", ex.Message, true);
                return null;
            }
        }

        private List<LayoutContent> GetLayoutDetail(int layoutID)
        {
            try
            {
                // Get layout details
                List<LayoutContent> layoutDetail = new List<LayoutContent>();

                PSDataSetTableAdapters.LayoutDetailTableAdapter taLayoutDetail = new PSDataSetTableAdapters.LayoutDetailTableAdapter();
                DataTable dtDetail = taLayoutDetail.GetDataByLayoutID(layoutID);

                LayoutContent tempContent;
                foreach (DataRow dr in dtDetail.Rows)
                {
                    tempContent = new LayoutContent(Convert.ToInt32(dr["ID"].ToString()), Convert.ToInt32(dr["LayoutID"].ToString()), Convert.ToInt32(dr["Sequence"].ToString()), Convert.ToInt32(dr["Duration"].ToString()), dr["Orientation"].ToString(), dr["ContentFileName"].ToString(), Convert.ToBoolean(dr["Stretch"].ToString()));
                    layoutDetail.Add(tempContent);
                }

                return layoutDetail;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetLayoutDetail", ex.Message, true);
                return null;
            }
        }

        public int AddLayoutHeader(Layout newLayout)
        {
            try
            {
                // Insert new layout header record
                PSDataSetTableAdapters.LayoutHeaderTableAdapter taLayoutHeader = new PSDataSetTableAdapters.LayoutHeaderTableAdapter();
                
                taLayoutHeader.InsertLayoutHeader(newLayout.Name, newLayout.ScheduleID);
                newLayout.LayoutID = (int)taLayoutHeader.GetNewestLayoutID();

                return newLayout.LayoutID;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.AddLayoutHeader", ex.Message, true);
                return -1;
            }
        }

        public int AddLayoutDetail(LayoutContent newLayoutContent)
        {
            try
            {
                // Insert new layout
                PSDataSetTableAdapters.LayoutDetailTableAdapter taLayoutDetail = new PSDataSetTableAdapters.LayoutDetailTableAdapter();

                taLayoutDetail.InsertLayoutDetail(newLayoutContent.LayoutID, newLayoutContent.Sequence, newLayoutContent.Duration, newLayoutContent.Orientation, newLayoutContent.ContentFileName, newLayoutContent.Stretch);
                newLayoutContent.ID = (int)taLayoutDetail.GetNewestLayoutDetailID();

                return newLayoutContent.ID;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.AddLayoutDetail", ex.Message, true);
                return -1;
            }
        }

        public void UpdateLayoutHeader(Layout updatedLayout)
        {
            try
            {
                // Update new layout
                PSDataSetTableAdapters.LayoutHeaderTableAdapter taLayoutHeader = new PSDataSetTableAdapters.LayoutHeaderTableAdapter();
                taLayoutHeader.UpdateLayoutHeader(updatedLayout.Name, updatedLayout.ScheduleID, updatedLayout.LayoutID);
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.UpdateLayoutHeader", ex.Message, true);
            }
        }

        public void UpdateLayoutDetail(LayoutContent updatedLayout)
        {
            try
            {
                // Update new layout
                PSDataSetTableAdapters.LayoutDetailTableAdapter taLayoutDetail = new PSDataSetTableAdapters.LayoutDetailTableAdapter();
                taLayoutDetail.UpdateLayoutDetail(updatedLayout.LayoutID, updatedLayout.Sequence, updatedLayout.Duration, updatedLayout.Orientation, updatedLayout.ContentFileName, updatedLayout.Stretch, updatedLayout.ID);
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.UpdateLayoutDetail", ex.Message, true);
            }
        }

        public bool DeleteLayout(Layout deletedLayout)
        {
            try
            {
                // Delete layout
                PSDataSetTableAdapters.LayoutHeaderTableAdapter taLayouts = new PSDataSetTableAdapters.LayoutHeaderTableAdapter();
                taLayouts.DeleteLayout(deletedLayout.LayoutID);
                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.DeleteLayout", ex.Message, true);
                return false;
            }
        }

        public bool DeleteLayoutDetail(LayoutContent deletedContent)
        {
            try
            {
                // Delete layout
                PSDataSetTableAdapters.LayoutDetailTableAdapter taLayouts = new PSDataSetTableAdapters.LayoutDetailTableAdapter();
                taLayouts.DeleteLayoutDetail(deletedContent.ID);
                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.DeleteLayoutDetail", ex.Message, true);
                return false;
            }
        }

        public string GetLayoutContentFileName(int id)
        {
            try
            {
                // Get layout image path
                PSDataSetTableAdapters.LayoutDetailTableAdapter taLayouts = new PSDataSetTableAdapters.LayoutDetailTableAdapter();
                string contentFileName = (string)taLayouts.GetLayoutContentFileName(id);
                return contentFileName;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetLayoutContentFileName", ex.Message, true);
                return string.Empty;
            }
        }

        public string GetLayoutImageFilePath(int layoutID)
        {
            try
            {
                // Get layout image path
                PSDataSetTableAdapters.LayoutDetailTableAdapter taLayouts = new PSDataSetTableAdapters.LayoutDetailTableAdapter();
                string imageFilePath = (string)taLayouts.GetContentFilePath(layoutID);
                return imageFilePath;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetLayoutImageFilePath", ex.Message, true);
                return string.Empty;
            }
        }

        public bool UpdateLayoutSchedule(Layout layout, int scheduleID)
        {
            try
            {
                // Update new layout
                PSDataSetTableAdapters.LayoutHeaderTableAdapter taLayouts = new PSDataSetTableAdapters.LayoutHeaderTableAdapter();
                taLayouts.UpdateSchedule(scheduleID, layout.LayoutID);
                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.UpdateLayoutSchedule", ex.Message, true);
                return false;
            }
        }

        public List<Schedule> GetSchedules()
        {
            try
            {
                List<Schedule> schedules = new List<Schedule>();

                PSDataSetTableAdapters.SchedulesTableAdapter taHeader = new PSDataSetTableAdapters.SchedulesTableAdapter();

                // Load schedule records
                DataTable dtSchedule = taHeader.GetData();

                // Add schedule to list
                Schedule tempSchedule;
                foreach (DataRow dr in dtSchedule.Rows)
                {
                    tempSchedule = new Schedule(Convert.ToInt32(dr["ScheduleID"].ToString()), dr["Name"].ToString(), Convert.ToBoolean(dr["Monday"].ToString()), Convert.ToBoolean(dr["Tuesday"].ToString()), Convert.ToBoolean(dr["Wednesday"].ToString()), Convert.ToBoolean(dr["Thursday"].ToString()), Convert.ToBoolean(dr["Friday"].ToString()), Convert.ToBoolean(dr["Saturday"].ToString()), Convert.ToBoolean(dr["Sunday"].ToString()), Convert.ToInt32(dr["StartDate"].ToString()), Convert.ToInt32(dr["EndDate"].ToString()), Convert.ToInt32(dr["StartTime"].ToString()), Convert.ToInt32(dr["EndTime"].ToString()));
                    schedules.Add(tempSchedule);
                }

                // Return list of all schedules
                return schedules;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.GetSchedules", ex.Message, true);
                return null;
            }
        }

        public int AddSchedule(Schedule newSchedule)
        {
            try
            {
                // Insert new schedule record
                PSDataSetTableAdapters.SchedulesTableAdapter taSchedule = new PSDataSetTableAdapters.SchedulesTableAdapter();

                taSchedule.InsertSchedule(newSchedule.Name, newSchedule.Monday, newSchedule.Tuesday, newSchedule.Wednesday, newSchedule.Thursday, newSchedule.Friday, newSchedule.Saturday, newSchedule.Sunday, newSchedule.StartDateAsNumber.ToString(), newSchedule.EndDateAsNumber.ToString(), newSchedule.StartTime, newSchedule.EndTime);
                newSchedule.ScheduleID = (int)taSchedule.GetNewestScheduleID();

                return newSchedule.ScheduleID;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.AddSchedule", ex.Message, true);
                return -1;
            }
        }

        public bool UpdateSchedule(Schedule updatedSchedule)
        {
            try
            {
                // Delete schedule record
                PSDataSetTableAdapters.SchedulesTableAdapter taSchedule = new PSDataSetTableAdapters.SchedulesTableAdapter();

                taSchedule.Update(updatedSchedule.Name, updatedSchedule.Monday, updatedSchedule.Tuesday, updatedSchedule.Wednesday, updatedSchedule.Thursday, updatedSchedule.Friday, updatedSchedule.Saturday, updatedSchedule.Sunday, updatedSchedule.StartDateAsNumber.ToString(), updatedSchedule.EndDateAsNumber.ToString(), updatedSchedule.StartTime, updatedSchedule.EndTime, updatedSchedule.ScheduleID);

                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.UpdateSchedule", ex.Message, true);
                return false;
            }
        }

        public bool DeleteSchedule(Schedule deletedSchedule)
        {
            try
            {
                // Delete schedule record
                PSDataSetTableAdapters.SchedulesTableAdapter taSchedule = new PSDataSetTableAdapters.SchedulesTableAdapter();

                taSchedule.Delete(deletedSchedule.ScheduleID);

                return true;
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("PSData.DeleteSchedule", ex.Message, true);
                return false;
            }
        }

    }
}
